package com.magic.shop.util;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

/**
 * jar包内的资源文件工具类
 */
public class JarResourceUtil {
    private static Logger LOG = LoggerFactory.getLogger(JarResourceUtil.class);

    /**
     * 获取文件的路径，本地运行就返回项目中文件的路径。服务器运行就返回服务器上此文件的路径
     *  服务器上没有文件时，会将jar包中的文件复制进去
     * @param targetPath 以项目的 resources 文件夹为根目录的文件路径，要求首位要有/或\（视操作系统而定）
     * @return 返回该文件的绝对路径。
     */
    public static String getFilePath(String targetPath) throws Exception {

        File targetFile = null;
        String targetFileName = "";
        try {
            //获取当前jar包所在的位置
            String basePath = System.getProperty("user.dir");
            LOG.info("System.getProperty(\"user.dir\")=" + basePath);
            LOG.info("targetPath=" + targetPath);
            //本地运行时的目标文件位置
            ///Users/xianshengzhang/myworks/efarmapi /src/main/resources
            StringBuffer localFilePath = new StringBuffer();
            localFilePath.append(basePath).append(File.separator).append("src").append(File.separator)
                    .append("main").append(File.separator).append("resources").append(targetPath);
            targetFile = new File(localFilePath.toString());

            if (targetFile.exists()){
                return targetFile.getPath();
            }
            targetFileName = targetFile.getName();
            //如果该文件不存在，说明是在服务器上运行
            //检测一下服务器上有没有这个文件
            String newPath = File.separator + "transfer";//服务器上的的存放路径
            targetFile = new File(basePath + newPath + File.separator + targetFileName);
            if (!targetFile.exists()){
                LOG.info("路径为:" + targetFile.getPath() + "的目标文件不存在，准备将jar包中的目标文件写入服务器的此文件中。");

                //如果线上目标和线下的目标文件都找不到的话
                //将jar包中的文件写入到服务器
                //获取目标文件的流
                //InputStream certStream = JarResourceUtil.class.getClassLoader().getResourceAsStream(targetPath);
                //直接从ClassPath根下获取
                InputStream certStream = JarResourceUtil.class.getResourceAsStream(targetPath);
                //将目标文件写入本地
                int index;
                byte[] bytes = new byte[1024];
                //创建要写入的文件流,位置为当前jar包所在位置下
                //先判断文件夹是否存在，不存在则先创建
                File file=new File(basePath + newPath);
                if(!file.exists()){//如果文件夹不存在
                    file.mkdirs();//创建文件夹
                }
                FileOutputStream downloadFile = new FileOutputStream(targetFile.getPath());
                while ((index = certStream.read(bytes)) != -1) {
                    downloadFile.write(bytes, 0, index);
                    downloadFile.flush();
                }
                certStream.close();
                downloadFile.close();
                //文件写入完成后,创建目标文件
                targetFile = new File(targetFile.getPath());
                LOG.info("目标文件写入成功");
            }
            return targetFile.getPath();
        }catch (Throwable t){
            LOG.error(t.getMessage(),t);
            LOG.error("获取目标文件或写入目标时出现错误，Exception：" + t.toString());
            throw new Exception("获取目标文件或写入目标时出现错误");
        }
    }

    public static String getRealPath(String targetPath) throws Exception {

        File targetFile = null;
        String targetFileName = "";
        try {
            //获取当前jar包所在的位置
            String basePath = System.getProperty("user.dir");
            LOG.info("System.getProperty(\"user.dir\")=" + basePath);
            LOG.info("targetPath=" + targetPath);
            //本地运行时的目标文件位置
            ///Users/xianshengzhang/myworks/efarmapi /src/main/resources
            StringBuffer localFilePath = new StringBuffer();
            localFilePath.append(basePath).append(File.separator).append("src").append(File.separator)
                    .append("main").append(File.separator).append("resources").append(File.separator).append(targetPath);
            targetFile = new File(localFilePath.toString());

            if (targetFile.exists()){
                return targetFile.getPath();
            }
            targetFileName = targetFile.getName();
            //如果该文件不存在，说明是在服务器上运行
            //检测一下服务器上有没有这个文件
            String newPath = File.separator + "transfer";//服务器上的的存放路径
            targetFile = new File(basePath + newPath + File.separator + targetFileName);
            if (!targetFile.exists()){
                LOG.info("路径为:" + targetFile.getPath() + "的目标不存在，准备生成文件夹。");

                //先判断文件夹是否存在，不存在则先创建
                File file=new File(basePath + newPath);
                if(!file.exists()){//如果文件夹不存在
                    file.mkdirs();//创建文件夹
                }
                //文件写入完成后,创建目标文件
                targetFile = new File(targetFile.getPath());
                LOG.info("目标文件写入成功");
            }
            return targetFile.getPath();
        }catch (Throwable t){
            LOG.error(t.getMessage(),t);
            LOG.error("获取目标文件或写入目标时出现错误，Exception：" + t.toString());
            throw new Exception("获取目标文件或写入目标时出现错误");
        }
    }

    public static String getRootRealPath(String targetPath) throws Exception {

        File targetFile = null;
        String targetFileName = "";
        try {
            //获取当前jar包所在的位置
            String basePath = System.getProperty("user.dir");
            LOG.info("System.getProperty(\"user.dir\")=" + basePath);
            LOG.info("targetPath=" + targetPath);
            //本地运行时的目标文件位置
            targetFileName = targetPath;
            //如果该文件不存在，说明是在服务器上运行
            //检测一下服务器上有没有这个文件
            targetFile = new File(basePath + File.separator + targetFileName);
            if (!targetFile.exists()){
                LOG.info("路径为:" + targetFile.getPath() + "的目标不存在，准备生成文件夹。");

                if(!targetFile.exists()){//如果文件夹不存在
                    targetFile.mkdirs();//创建文件夹
                }
                //文件写入完成后,创建目标文件
                targetFile = new File(targetFile.getPath());
                LOG.info("目标文件写入成功");
            }
            return targetFile.getPath();
        }catch (Throwable t){
            LOG.error(t.getMessage(),t);
            LOG.error("获取目标文件或写入目标时出现错误，Exception：" + t.toString());
            throw new Exception("获取目标文件或写入目标时出现错误");
        }
    }

    public static String buildFilePath(String ... str) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length; i ++){
            sb.append(File.separator).append(str[i]);
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String s = buildFilePath("usr", "local", "test.png");
        System.out.println(s);
    }

    /**
     * 获取jar包根目录
     * @return
     */
    public static String getJarRootDir(){
        String jarRootDir = System.getProperty("user.dir");
        return jarRootDir;
    }

    /**
     * 获取jar包根目录下的文件路径
     * @param str
     * @return
     */
    public static String getJarRootFilePath(String ... str){
        String filePath = JarResourceUtil.getJarRootDir() + JarResourceUtil.buildFilePath(str);
        return filePath;
    }
}
